package com.xianrenit.xianrenpuzi.manager.service.impl;

import com.xianrenit.xianrenpuzi.common.handler.exception.SpzxException;
import com.xianrenit.xianrenpuzi.manager.interceptor.SpzxLoginAuthInterceptor;
import com.xianrenit.xianrenpuzi.manager.mapper.SysMenuMapper;
import com.xianrenit.xianrenpuzi.manager.service.SysMenuService;
import com.xianrenit.xianrenpuzi.model.entity.sys.SysMenu;
import com.xianrenit.xianrenpuzi.model.entity.sys.SysUser;
import com.xianrenit.xianrenpuzi.model.result.ResultCodeEnum;
import com.xianrenit.xianrenpuzi.model.vo.sys.SysMenuVo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysMenuServiceImpl implements SysMenuService {
    @Resource
    SysMenuMapper sysMenuMapper;
    //使用Mapper
    @Override
    public List<SysMenu> listNestedMenus() {
        //sql：能不使用联查就不要使用
        //1、查询所有的菜单
        List<SysMenu> menus = sysMenuMapper.selectAll();
        //2、挑选出一级菜单集合: sysmenu的parent_id=0表示第一级菜单
        List<SysMenu> parents = menus.stream()
                .filter(menu -> menu.getParentId().equals(0L)) //挑选parentId=0的 剩下的被过滤掉
                .collect(Collectors.toList());//将前面的结果转为List集合
        buildMenuTree(menus, parents);
        return parents;
    }
    //可以使用递归封装多层菜单组装逻辑
//    private void buildMenuTree(List<SysMenu> menus, List<SysMenu> parents) {
//        //只能借助于栈来实现：  将每一个遍历到的parent或者下一级的菜单  每一个 都存到栈中，然后再一个个的出栈，查找它的下一级，直到没有下一级
//        for (int i = 0; i < parents.size(); i++) {
//            SysMenu parent = parents.get(i);
//            while(parent!=null){
//                //3、为每个一级菜单挑选它的下一级封装
//
//                //如果menu的parent_id 等于parent的id
//                List<SysMenu> children = menus.stream().filter(menu -> menu.getParentId().equals(parent.getId()))
//                        .collect(Collectors.toList());
//                if(!CollectionUtils.isEmpty(children)){
//                    parent.setChildren(children);
//                }
//                //如果二级菜单下还有三级菜单
////                buildMenuTree(menus , children);
//                parents = children;
//
//            }
//        }
//
//
//    }
    private void buildMenuTree(List<SysMenu> menus, List<SysMenu> parents) {
        if(CollectionUtils.isEmpty(parents)){
            return;
        }
        //3、为每个一级菜单挑选它的下一级封装
        parents.forEach(parent->{
            //如果menu的parent_id 等于parent的id
            List<SysMenu> children = menus.stream().filter(menu -> menu.getParentId().equals(parent.getId()))
                    .collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(children)){
                parent.setChildren(children);
            }
            //如果二级菜单下还有三级菜单
            buildMenuTree(menus , children);
        });
    }


//    // 所有分类
//    List<GoodsType> menus = goodTypeDao.selectAll();
//    // 一级分类
//    List<GoodsType> parents = menus.stream()
//            .filter(menu -> menu.getPId().equals(-1))
//            .collect(Collectors.toList());
//    List<GoodsTypeVo> goodsTypeVos = parents.stream().map(goodsType -> {
//        GoodsTypeVo goodsTypeVo = new GoodsTypeVo();
//        goodsTypeVo.setId(goodsType.getGoodsTypeId());
//        goodsTypeVo.setState(goodsType.getGoodsTypeState() == 1 ? "open" : "closed");
//        Attributes attributes = new Attributes();
//        attributes.setState(goodsType.getGoodsTypeState());
//        goodsTypeVo.setAttributes(attributes);
//        goodsTypeVo.setText(goodsType.getGoodsTypeName());
//        goodsTypeVo.setIconCls("goods-type");
//        goodsTypeVo.setChildren(null);
//        return goodsTypeVo;
//    }).collect(Collectors.toList());
//
//    buildGoodsTypeTrees(menus, goodsTypeVos);
//        return goodsTypeVos;
//}
//
//    private void buildGoodsTypeTrees(List<GoodsType> menus, List<GoodsTypeVo> goodsTypeVos) {
//        if (CollectionUtils.isEmpty(goodsTypeVos)) {
//            return;
//        }
//        goodsTypeVos.forEach(goodsType -> {
//            // 遍历所有的一级分类，组装儿子
//            List<GoodsTypeVo> goodsTypeSon = menus.stream()
//                    .filter(son -> son.getPId() == goodsType.getId())
//                    .map(son -> {
//                        GoodsTypeVo goodsTypeVo = new GoodsTypeVo();
//                        goodsTypeVo.setId(son.getGoodsTypeId());
//                        goodsTypeVo.setState(son.getGoodsTypeState() == 1 ? "open" : "closed");
//                        Attributes attributes = new Attributes();
//                        attributes.setState(son.getGoodsTypeState());
//                        goodsTypeVo.setAttributes(attributes);
//                        goodsTypeVo.setText(son.getGoodsTypeName());
//                        goodsTypeVo.setIconCls("goods-type");
//                        goodsTypeVo.setChildren(null);
//                        return goodsTypeVo;
//                    }).collect(Collectors.toList());
//            if (!CollectionUtils.isEmpty(goodsTypeSon)) {
//                goodsType.setChildren(goodsTypeSon);
//                buildGoodsTypeTrees(menus, goodsTypeSon);
//            }
//        });
//    }


    @Override
    public void deleteById(Long id) {
        //只能删除没有下一级菜单的菜单
        boolean hasChildren = sysMenuMapper.hasChildren(id);
        if(hasChildren){
            throw new SpzxException(ResultCodeEnum.MENU_HAS_CHILDREN_ERROR);
        }
        //逻辑删除
        sysMenuMapper.deleteById(id);
    }

    @Override
    public void save(SysMenu sysMenu) {
        //新增：是添加下一级菜单，所以必须传入parent_Id的值
        sysMenuMapper.save(sysMenu);
    }

    @Override
    public SysMenu getById(Long id) {
        return sysMenuMapper.selectById(id);
    }

    @Override
    public void update(SysMenu sysMenu) {
        sysMenuMapper.update(sysMenu);
    }

    @Override
    public List<Long> listMenuIdsByRoleId(Long roleId) {
        /*
            根据角色id查询它已分配的菜单id列表
            sys_role_menu:  roleId  menuId
            不能查询一级/父 菜单

            sys_role_menu 和 sys_menu联查，只查询已分配的二级菜单列表id

         */
        return sysMenuMapper.selectMenuIdsByRoleId(roleId);
    }
    //查询登录用户的可以访问的菜单列表
    @Override
    public List<SysMenuVo> listMenus() {
        //1、获取用户id
        SysUser sysUser = SpzxLoginAuthInterceptor.THREAD_LOCAL.get();
        Long userId = sysUser.getId();
        //2、根据userId查询可以访问的菜单列表
        List<SysMenu> sysMenus = sysMenuMapper.listMenusByUserId(userId);
        //将sysMenu对象转为sysMenuVo对象
        List<SysMenu> parents = sysMenus.stream().filter(sysMenu -> sysMenu.getParentId().equals(0L)).collect(Collectors.toList());
        buildMenuTree(sysMenus , parents);

        //map:可以将遍历的对象转为其他类型的对象
        List<SysMenuVo> menuVos = parents.stream().map(parent -> {
            //转换parent为SysMenuVo对象
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setTitle(parent.getTitle());
            sysMenuVo.setName(parent.getComponent());
            //children不能设置 空集合 否则前端有bug
            if(!CollectionUtils.isEmpty(parent.getChildren())){
                //转换parent的Children为SysMenuVo对象集合
                List<SysMenuVo> children = parent.getChildren().stream().map(child -> {
                    SysMenuVo menuVo = new SysMenuVo();
                    menuVo.setChildren(null);
                    menuVo.setName(child.getComponent());
                    menuVo.setTitle(child.getTitle());
                    return menuVo;
                }).collect(Collectors.toList());

                sysMenuVo.setChildren(children);
            }

            return sysMenuVo;
        }).collect(Collectors.toList());

        return menuVos;
    }
}
